package durose.durose;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;

import javax.servlet.ServletContext;

import org.springframework.util.ResourceUtils;

import durose.system.pojo.DuRose;
import durose.util.DuroseCharFilterUtil;
import durose.util.MybatisGenerator;

public class DuRoseGenerator {
	
	private ServletContext servletContext;
	
	private String contextPath;
	
	//模版数据的加载目录
	private String loadModularPath = "static"+File.separator+"durose";
	
	//jsp页面的输出目录
	private String jspOutputPath = "WEB-INF"+File.separator+"view"+File.separator+"system"+File.separator+"modular";
	
	//js文件的输出目录
	private String jsOutputPath = "static"+File.separator+"js"+File.separator+"modular";
	
	//java文件的输出目录
	private String javaControllerPath="src"+File.separator+"main"+File.separator+"java"+File.separator+"durose"+File.separator+"modular"+File.separator+"controller";
	
	private String javaServicePath = "src"+File.separator+"main"+File.separator+"java"+File.separator+"durose"+File.separator+"system"+File.separator+"service";
	
	private String javaServiceImplPath =  "src"+File.separator+"main"+File.separator+"java"+File.separator+"durose"+File.separator+"system"+File.separator+"serviceImpl";
	//mybaits generator.xml类加载器输出目录
	private String mybatisGeneratorPathClass = "target"+File.separator+"classes";
	
	//Spring容器处理一对多的输出目录
	private String springContextPath = "src"+File.separator+"main"+File.separator+"java"+File.separator+"durose"+File.separator+"system"+File.separator+"springUtil";
	
	
	public DuRoseGenerator(ServletContext servletContext){
		this.servletContext = servletContext;
		this.contextPath = servletContext.getRealPath("/");
		this.loadModularPath = contextPath+this.loadModularPath;
		this.jspOutputPath = contextPath+this.jspOutputPath;
		this.jsOutputPath = contextPath+this.jsOutputPath;
		try {
			String javaClassPath = ResourceUtils.getURL("classpath:").getPath().replaceFirst("/", "");
			File f = new File(javaClassPath);
			javaControllerPath = f.getParentFile().getParentFile().getAbsolutePath()+File.separator+javaControllerPath;
			javaServicePath = f.getParentFile().getParentFile().getAbsolutePath()+File.separator+javaServicePath;
			javaServiceImplPath = f.getParentFile().getParentFile().getAbsolutePath()+File.separator+javaServiceImplPath;
			mybatisGeneratorPathClass = f.getParentFile().getParentFile().getAbsolutePath()+File.separator+mybatisGeneratorPathClass;
			springContextPath = f.getParentFile().getParentFile().getAbsolutePath()+File.separator+springContextPath;
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//杜玫瑰核心代码生成控制类
	public void DuRoseInit(List<DuRose> duroses){
		try {
			initJsp(duroses);
			initJspAdd(duroses);
			initJspEdit(duroses);
			initJs(duroses);
			initJavaController(duroses);
			initJavaService(duroses);
			initJavaServiceImpl(duroses);
			initMybatisGenerator(duroses);
			initSpringContext(duroses);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 初始化jsp页面，读入参数，读入页面、修改增添数据、输出到jsp页面目录
	 * @return
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	public void initJsp(List<DuRose> duroses) throws FileNotFoundException, IOException{
		String tableName = duroses.get(0).getTableName();
		File f = new File(loadModularPath,"jsp_modular.durose");
		File f1 = new File(jspOutputPath+File.separator+tableName,tableName+".jsp");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$table$"), tableName);
				thisLine = thisLine.replaceAll(Matcher.quoteReplacement("$thead$"), initTableHead(duroses));
				bw.write(thisLine);
				bw.write("\n");
			}
		}
		
	}
	
	
	
	/**
	 * 初始化jsp增加页面
	 * @param durose
	 * @return
	 * @throws IOException 
	 */
	public void initJspAdd(List<DuRose> duroses) throws IOException{
		String tableName = duroses.get(0).getTableName();
		File f = new File(loadModularPath,"jsp_modular_add.durose");
		File f1 = new File(jspOutputPath+File.separator+tableName,tableName+"_add.jsp");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$add$"), Matcher.quoteReplacement(DuRoseGeneratorJspAdd.initInputAdd(duroses)));
				bw.write(thisLine);
				bw.write("\n");
			}
		}
	}
	
	/**
	 * 初始化jsp编辑页面
	 * @param durose
	 * @return
	 * @throws IOException 
	 */
	public void initJspEdit(List<DuRose> duroses) throws IOException{
		String tableName = duroses.get(0).getTableName();
		File f = new File(loadModularPath,"jsp_modular_edit.durose");
		File f1 = new File(jspOutputPath+File.separator+tableName,tableName+"_edit.jsp");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$edit$"), Matcher.quoteReplacement(DuRoseGeneratorJspEdit.initInputAdd(duroses)));
				bw.write(thisLine);
				bw.write("\n");
			}
		}
	}
	
	/**
	 * 初始化js页面
	 * @param durose
	 * @return
	 * @throws Exception 
	 */
	public void initJs(List<DuRose> duroses) throws Exception{
		String tableName = duroses.get(0).getTableName();
		File f = new File(loadModularPath,"js_modular.durose");
		File f1 = new File(jsOutputPath+File.separator+tableName,tableName+".js");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$tableName$"),tableName);
				if(thisLine.indexOf("$columnName$")!=-1){
					thisLine = thisLine.replace("$columnName$", DuRoseGeneratorJs.initColumnName(duroses));
				}
				if(thisLine.indexOf("$primary$")!=-1){
					thisLine = thisLine.replace("$primary$", getPrimary(duroses));
				}
				bw.write(thisLine);
				bw.write("\n");
			}
		}
	}
	
	/**
	 * 初始化javaController页面
	 * @param duroses
	 * @return
	 * @throws Exception
	 */
	public void initJavaController(List<DuRose> duroses) throws Exception{
		String tableName = duroses.get(0).getTableName();
		String ClassName = DuroseCharFilterUtil.toUpperFristChar(tableName);
		File f = new File(loadModularPath,"controller_modular.durose");
		File f1 = new File(javaControllerPath,ClassName+"Controller.java");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$ClassName$"),ClassName);
				thisLine = thisLine.replaceAll(Matcher.quoteReplacement("$tableName$"), tableName);
				if(thisLine.indexOf("$foreginTablePack$")!=-1){
					//初始化导包类
					thisLine = thisLine.replace("$foreginTablePack$", DuRoseJavaControllerGenerator.initForeginTablePack(duroses));
				}
				if(thisLine.indexOf("$foreginTableService$")!=-1){
					//初始化service类
					thisLine = thisLine.replace("$foreginTableService$", DuRoseJavaControllerGenerator.initForeginTableService(duroses));
				}
				if(thisLine.indexOf("$foreginTableEdit$")!=-1){
					//初始化页面跳转时，关联的外表查询数据
					thisLine = thisLine.replace("$foreginTableEdit$",DuRoseJavaControllerGenerator.initForeginTableEdit(duroses));
				}
				bw.write(thisLine);
				bw.write("\n");
			}
		}
	}
	
	/**
	 * 初始化Java service
	 * @param durose
	 * @return
	 * @throws Exception 
	 */
	public void initJavaService(List<DuRose> duroses) throws Exception{
		String tableName = duroses.get(0).getTableName();
		String ClassName = DuroseCharFilterUtil.toUpperFristChar(tableName);
		File f = new File(loadModularPath,"service_modular.durose");
		File f1 = new File(javaServicePath,ClassName+"Service.java");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$ClassName$"),ClassName);
				thisLine = thisLine.replaceAll(Matcher.quoteReplacement("$tableName$"), tableName);
				bw.write(thisLine);
				bw.write("\n");
			}
		}
	}
	
	/**
	 * 初始化Java serviceImpl
	 * @param durose
	 * @return
	 * @throws Exception 
	 */
	public void initJavaServiceImpl(List<DuRose> duroses) throws Exception{
		String tableName = duroses.get(0).getTableName();
		String ClassName = DuroseCharFilterUtil.toUpperFristChar(tableName);
		String QueryName = DuroseCharFilterUtil.toUpperFristChar(duroses.get(0).getQueryName());
		File f = new File(loadModularPath,"serviceImpl_modular.durose");
		File f1 = new File(javaServiceImplPath,ClassName+"ServiceImpl.java");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$ClassName$"),ClassName);
				thisLine = thisLine.replaceAll(Matcher.quoteReplacement("$tableName$"), tableName);
				if(thisLine.indexOf("$QueryName$")!=-1){
					thisLine = thisLine.replace("$QueryName$", QueryName);
				}
				bw.write(thisLine);
				bw.write("\n");
			}
		}
	}
	
	/**
	 * 初始化mybaits自动生成，并执行
	 * @param duroses
	 * @return
	 * @throws Exception
	 */
	public void initMybatisGenerator(List<DuRose> duroses) throws Exception{
		String tableName = duroses.get(0).getTableName();
		String ClassName = DuroseCharFilterUtil.toUpperFristChar(tableName);
		
		File f = new File(loadModularPath,"mybatis_generator.durose");
		File f2 = new File(mybatisGeneratorPathClass,"generatorConfig.xml");
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw1 = new BufferedWriter(new FileWriter(f2))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replace("$ClassName$",ClassName);
				thisLine = thisLine.replace("$tableName$", tableName);
				bw1.write(thisLine);
				bw1.write("\n");
			}
		}
		MybatisGenerator.main(null);
	}
	
	/**
	 * 初始化spring容器处理的返回数据
	 * @param duroses
	 * @return
	 * @throws Exception
	 */
	public void initSpringContext(List<DuRose> duroses) throws Exception{
		String tableName = duroses.get(0).getTableName();
		String ClassName = DuroseCharFilterUtil.toUpperFristChar(tableName);
		File f = new File(loadModularPath,"springFactory_modular.durose");
		File f1 = new File(springContextPath,"Spring"+ClassName+"Factory.java");
		if(!f1.getParentFile().exists()){
			f1.getParentFile().mkdirs();
		}
		try(BufferedReader br = new BufferedReader(new FileReader(f));BufferedWriter bw = new BufferedWriter(new FileWriter(f1))){
			String s;
			while((s=br.readLine())!=null){
				String thisLine = s.replaceAll(Matcher.quoteReplacement("$ClassName$"),ClassName);
				thisLine = thisLine.replaceAll(Matcher.quoteReplacement("$tableName$"), tableName);
				if(thisLine.indexOf("$foreginServicePack$")!=-1){
					//初始化导包类
					thisLine = thisLine.replace("$foreginServicePack$", DuRoseGeneratorSpring.initForeginTablePack(duroses));
				}
				
				if(thisLine.indexOf("$foreginService$")!=-1){
					//初始化service类
					thisLine = thisLine.replace("$foreginService$", DuRoseGeneratorSpring.initForeginTableService(duroses));
				}
				if(thisLine.indexOf("$initMap$")!=-1){
					//初始化map转换
					thisLine = thisLine.replace("$initMap$",DuRoseGeneratorSpring.initMap(duroses));
				}
				bw.write(thisLine);
				bw.write("\n");
			}
		}
		
	}
	
	
	//找到list中的主键
	private String getPrimary(List<DuRose> duroses) throws Exception{
		boolean getPrimary = false;
		String primary="";
		for(DuRose durose:duroses){
			if(durose.getColumnType().equals("primary")){
				primary = durose.getColumnName();
				getPrimary=true;
			}
		}
		if(!getPrimary){
			throw new Exception("必须指定一个主键！");
		}else{
			return primary;
		}
	}
	
	private String initTableHead(List<DuRose> duroses){
		String tableHead="<thead>\n";
		for(DuRose durose:duroses){
			tableHead+="<th>";
			tableHead+=durose.getColumnChinaName();
			tableHead+="</th>";
		}
		tableHead+="<th>";
		tableHead+="编辑";
		tableHead+="</th>";
		tableHead+="<th>";
		tableHead+="删除";
		tableHead+="</th>\n";
		tableHead+="</thead>";
		return tableHead;
	}
	
	
	public ServletContext getServletContext() {
		return servletContext;
	}

	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	public String getContextPath() {
		return contextPath;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}

	public String getLoadModularPath() {
		return loadModularPath;
	}

	public void setLoadModularPath(String loadModularPath) {
		this.loadModularPath = loadModularPath;
	}

	public String getJspOutputPath() {
		return jspOutputPath;
	}

	public void setJspOutputPath(String jspOutputPath) {
		this.jspOutputPath = jspOutputPath;
	}

	public String getJsOutputPath() {
		return jsOutputPath;
	}

	public void setJsOutputPath(String jsOutputPath) {
		this.jsOutputPath = jsOutputPath;
	}
	
	
}
